package utils;

import cn.hutool.core.date.DateUtil;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;

public class MyTestResultForHtml {
    private MyTestResultForHtml() {

    }

    private static class Inner {
        private static final MyTestResultForHtml myTestResultForHtml = new MyTestResultForHtml();
    }

    public static MyTestResultForHtml newInstance() {
        return Inner.myTestResultForHtml;
    }

    /**
     * 创建测试报告文件
     *
     * @throws IOException
     */
    private File creatResultFile() throws IOException {
        File file = new File("MyTestResultForHtml.html");
        if (!file.exists()) {
            System.out.println("MyTestResultForHtml===" + file.exists());
            assert file.createNewFile();
        }
        return file;
    }

    /**
     * 初始化生成html测试报告文件
     *
     * @throws IOException
     */
    public void initTestResultForHtml() throws IOException {
        File file = creatResultFile();

        BufferedWriter bw = new BufferedWriter(new FileWriter(file));
        String sb = "<html><head>" +
                "<title>接口自动化测试报告</title>" +
                "<meta http-equiv=\"Content-Type\" content=\"text/html\"  charset=\"utf-8\"/>" +
                "</head>" +
                "<style font-family=\"arial\";type=\"text/css\";>" +
                "table,td,th{border-collapse:collapse;border:1px solid #000;}" +
                "</style>" +
                "<body bgcolor=\"#FFF8DC\">" +
                "<table align=\"center\" cellpadding=\"5\" style=\"table-layout:fixed;word-break:break-all;\">" +
                "<tr style=\"font-family:arial;color:blue;font-size:20px;\">" +
                "<th colspan=\"6\" style=\"text-align:center;text-shadow: 5px 5px 5px gray;\">" +
                "接口自动化测试报告" +
                "</th></tr>" +
                "<tr style=\"font-family:arial;color:blue;font-size:16px;\">" +
                "<th align=\"left\">测试设备</th>" +
                "<th colspan = \"5\" align=\"left\">" + "版本信息" + "</th>" +
                "</tr><tr style=\"font-family:arial;color:blue;font-size:16px;\">" +
                "<th align=\"left\">测试开始时间</th>" +
                "<th colspan = \"5\" align=\"left\">" + DateUtil.format(DateUtil.date(), "yyyy/MM/dd HH:mm:ss") + "</th></tr>" +
                "<tr style=\"font-family:arial;color:blue;font-size:16px;\">" +
                "<th align=\"left\">测试结束时间</th>" +
                "<th colspan = \"5\" align=\"left\" id=\"endTime\"></th>" +
                "</tr><tr style=\"font-family:arial;color:blue;font-size:16px;\">" +
                "<th align=\"left\">测试用例总数</th>" +
                "<th colspan = \"5\" align=\"left\" id=\"count\" style=\"color:red;\"></th></tr>" +
                "<tr style=\"font-family:arial;color:blue;font-size:16px;\">" +
                "<th align=\"left\">测试失败率</th>" +
                "<th colspan = \"5\" align=\"left\" style=\"color:red\" id=\"failurerate\"></th></tr>" +
                "<tr style=\"font-family:arial;color:blue;font-size:16px;\">" +
                "<th align=\"left\" width=\"16%\">测试用例编号</th>" + "<th width=\"25%\">测试项或操作步骤</th>" + "<th width=\"15%\">期望结果</th>" +
                "<th width=\"7%\">测试结果</th><th width=\"7%\">测试运行时间</th><th width=\"30%\">备注</th></tr>";
        bw.write(sb);
        bw.flush();
        bw.close();
    }

    /**
     * 向html文件写入测试结果
     */
    public void printTestResult(String number, String operatingSteps, String expected, Object actual, String remark) {
        try {
            File file = creatResultFile();
            FileOutputStream fos = new FileOutputStream(file, true);

            fos.write(("<tr><td>" + number + "</td>").getBytes());
            fos.write(("<td>" + operatingSteps + "</td>").getBytes());
            fos.write(("<td>" + expected + "</td>").getBytes());
            if (actual.equals("pass"))
                fos.write(("<td style=\"font-family:arial;color:green;font-size:16px;\">" + actual + "</td>").getBytes());
            else
                fos.write(("<td style=\"font-family:arial;color:red;font-size:16px;\">" + actual + "</td>").getBytes());
            fos.write(("<td>" + DateUtil.format(DateUtil.date(),"HH:mm:ss") + "</td>").getBytes());
            if (remark != null && remark.length() > 203) {
                fos.write(("<td><div title='" + remark.replace("'", "\"") + "'>" + remark.substring(0, 203) + "..." + "</div></td></tr>").getBytes());
            } else {
                fos.write(("<td>" + remark + "</td></tr>").getBytes());
            }

            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void printTestResult(String number, String operatingSteps, String expected, Object actual) {
        printTestResult(number, operatingSteps, expected, actual, "");
    }

    /**
     * 结果统计
     *
     * @throws IOException
     */
    public void statisticsResult() throws IOException {
        File file = creatResultFile();
//        String htmlEnd="</table></body></html>";
        int passCount = 0;
        int errorCount = 0;
        int failCount = 0;
        Document doc = Jsoup.parse(file, "UTF-8");

        Elements td = doc.getElementsByTag("td");

        for (Element element : td) {
            if (element.text().equals("pass")) {
                passCount++;
            }
        }
        for (Element element : td) {
            if (element.text().equals("error")) {
                errorCount++;
            }
        }
        for (Element element : td) {
            if (element.text().equals("fail")) {
                failCount++;
            }
        }
        int caseCount = passCount + failCount + errorCount;//测试用例总数

        Element el_caseCount = doc.getElementById("count");
        Element el_endTime = doc.getElementById("endTime");
        Element el_failurerate = doc.getElementById("failurerate");

        assert el_endTime != null;
        el_endTime.text(DateUtil.format(DateUtil.date(),"yyyy/MM/dd HH:mm:ss"));
        assert el_caseCount != null;
        el_caseCount.text(caseCount + "");
        System.out.println("passCount=" + passCount);
        assert el_failurerate != null;
        el_failurerate.text(Math.round((caseCount - passCount) * 10000 / caseCount) / 100.0 + "%");

        assert file.delete();
        assert file.createNewFile();//重新创建本地文件

        //将修改好的html打印到文件
        FileOutputStream fos = new FileOutputStream(file, true);
        fos.write(doc.html().getBytes());
//        fos.write(htmlEnd.getBytes());
        fos.close();
    }
}